﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace WCSWaitForm
{
    public partial class BaseForm : Form, IMessageFilter
    {
        private BackgroundWorker backWorker_wait = null;
        private IntPtr intPrt_wait = IntPtr.Zero;
        private Screen screen_wait = null;
        private ShowWaitSite showWaitSite = ShowWaitSite.CenterOwner;

        protected static bool canClick = true;
        protected bool afterMoveMax = false;

        public BaseForm()
        {
            InitializeComponent();
            SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
            SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);
        }

        protected void ShowWaitForm()
        {
            ShowWaitForm(ShowWaitSite.CenterOwner);
        }
        protected void ShowWaitForm(ShowWaitSite showWaitSite)
        {
            this.showWaitSite = showWaitSite;
            if (backWorker_wait != null)
            {
                backWorker_wait.Dispose();
                backWorker_wait.DoWork -= new DoWorkEventHandler(backWorker_wait_DoWork);
                backWorker_wait.Disposed -= new EventHandler(backWorker_wait_Disposed);
                backWorker_wait = null;
            }
            screen_wait = Screen.FromControl(this);
            canClick = false;
            LockWindow(this.Handle, false);
            backWorker_wait = new BackgroundWorker();
            backWorker_wait.DoWork += new DoWorkEventHandler(backWorker_wait_DoWork);
            backWorker_wait.Disposed += new EventHandler(backWorker_wait_Disposed);
            backWorker_wait.RunWorkerAsync();
        }

        private void backWorker_wait_DoWork(object sender, DoWorkEventArgs e)
        {
            const int childFormWidth = 310;
            const int childFormHeight = 110;

            int formLocation_X = 0;
            int formLocation_Y = 0;
            int formSize_Width = 0;
            int formSize_Height = 0;
            int childFormLocation_X = 0;
            int childFormLocation_Y = 0;

            switch (showWaitSite)
            {
                case ShowWaitSite.CenterApplication:
                    break;
                case ShowWaitSite.CenterScreen:
                    formLocation_X = 0;
                    formLocation_Y = 0;
                    formSize_Width = screen_wait.WorkingArea.Width;
                    formSize_Height = screen_wait.WorkingArea.Height;
                    childFormLocation_X = (formSize_Width - childFormWidth) / 2;
                    childFormLocation_Y = (formSize_Height - childFormHeight) / 2;
                    break;
                case ShowWaitSite.CenterOwner:
                    formLocation_X = this.Location.X;
                    formLocation_Y = this.Location.Y;
                    formSize_Width = this.Size.Width;
                    formSize_Height = this.Size.Height;
                    childFormLocation_X = formLocation_X + (formSize_Width - childFormWidth) / 2;
                    childFormLocation_Y = formLocation_Y + (formSize_Height - childFormHeight) / 2;
                    break;
            }

            Form_Opacity form_Opacity = new Form_Opacity();
            form_Opacity.Location = new Point(formLocation_X, formLocation_Y);
            form_Opacity.Size = new Size(formSize_Width, formSize_Height);
            form_Opacity.TopMost = true;
            //form_Opacity.BringToFront();//偶尔无效

            form_Opacity.childForm = new Form_Wait();
            form_Opacity.childForm.Location = new Point(childFormLocation_X, childFormLocation_Y);
            form_Opacity.childForm.TopMost = true;

            intPrt_wait = form_Opacity.Handle;
            form_Opacity.ShowDialog();
        }
        private void backWorker_wait_Disposed(object sender, EventArgs e)
        {
            WaitFormTools.CloseForm(intPrt_wait);
        }

        protected void CloseWaitForm()
        {
            if (backWorker_wait != null)
            {
                backWorker_wait.Dispose();
                backWorker_wait.DoWork -= new DoWorkEventHandler(backWorker_wait_DoWork);
                backWorker_wait.Disposed -= new EventHandler(backWorker_wait_Disposed);
                backWorker_wait = null;
                intPrt_wait = IntPtr.Zero;
                canClick = true;
                LockWindow(this.Handle, true);
            }
            Application.DoEvents();
        }

        /// <summary>
        /// 锁定/解锁键盘鼠标消息
        /// </summary>
        protected void LockWindow(IntPtr intPtr, bool enable)
        {
            WaitFormTools.EnableWindow(intPtr, enable);
            //WaitFormTools.BlockInput(!enable);
        }

        #region 窗口控件拖动

        protected const int WM_SYSCOMMAND = 0x0112;
        protected const int SC_MOVE = 0xF010;
        protected const int HTCAPTION = 0x2;
        /// <summary>
        /// 需要有移动效果的控件绑定此事件
        /// 继承窗口不能在设计器里面加载此事件，应在代码里添加
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Form_Control_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.Handle != WaitFormTools.GetForegroundWindow())
            {
                return;
            }
            if (e.Button == MouseButtons.Left)
            {
                WaitFormTools.ReleaseCapture();
                WaitFormTools.SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
                if (afterMoveMax)
                {
                    Rectangle rect = Screen.FromControl(this).WorkingArea;
                    this.MinimumSize = new Size(rect.Width, rect.Height);
                    this.MaximumSize = new Size(rect.Width, rect.Height);
                    this.WindowState = FormWindowState.Maximized;
                }
            }
        }

        #endregion

        /// <summary>
        /// 双击最大化事件
        /// </summary>
        protected void Form_Control_Max_DoubleClick(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            if (!Screen.FromControl(this).Primary)
            {
                this.Left = Screen.PrimaryScreen.Bounds.Width;
                this.Top = 0;
            }
            this.WindowState = FormWindowState.Maximized;
        }

        public bool PreFilterMessage(ref Message m)
        {
            //可以通过ImessageFilter接口下的PreFilterMessage方法、Application类的AddMessageFilter方法，
            //RemoveMessageFilter方法和Message结构的Msg属性来禁用鼠标左键。
            //Message结构包装Windows发送的消息，可使用该结构包装消息，并将其分配给窗口过程以进行调度，
            //还可以使用该结构获取系统向应用程序或控件发送的关于某个消息的信息。 
            //使用PreFilterMessage方法在调度消息之前将其筛选出来。
            //Application.AddMessageFilter(this);
            //Application.RemoveMessageFilter(this);
            ////不响应鼠标左键消息
            //if (m.Msg >= 513 && m.Msg <= 515)
            //{
            //    return true;
            //}
            //return false;
            if (!canClick)//鼠标左键按下、弹起和双击的消息
            {
                return true;//拦截消息
            }
            return false;//不拦截消息
        }

        #region 阻止接收消息

        //private const int WM_NCHITTEST = 0x84;
        //protected override void WndProc(ref Message m)
        //{
        //    // 拦击标题栏鼠标位置事件，但是拦截不了最小最大关闭按钮
        //    base.WndProc(ref m);
        //    if (m.Msg == WM_NCHITTEST)
        //    {
        //        switch (m.Result.ToInt32())
        //        {
        //            //case 1://客户区
        //            //    m.Result = new IntPtr(0);
        //            //    break;
        //            case 2://标题栏
        //                m.Result = new IntPtr(0);
        //                break;
        //            //case 20:
        //            //    m.Result = new IntPtr(0);
        //            //    break;
        //            //default:
        //            //    Console.WriteLine(m);
        //            //    break;
        //        }
        //    }
        //    // 下面的方法，除了首次双击标题栏，都可以拦截
        //    //if (m.Msg == 0x112)
        //    //{
        //    //    switch ((int)m.WParam)
        //    //    {
        //    //        //禁止双击标题栏关闭窗体
        //    //        case 0xF063:
        //    //        case 0xF093:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止拖拽标题栏还原窗体
        //    //        case 0xF012:
        //    //        case 0xF010:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止双击标题栏
        //    //        case 0xf122:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止关闭按钮
        //    //        case 0xF060:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止最大化按钮
        //    //        case 0xf020:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止最小化按钮
        //    //        case 0xf030:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //        //禁止还原按钮
        //    //        case 0xf120:
        //    //            m.WParam = IntPtr.Zero;
        //    //            break;
        //    //    }
        //    //}
        //    //base.WndProc(ref m);
        //}

        #endregion

    }
}
